
#ifndef LOWLEVELDISK_H_
#define LOWLEVELDISK_H_


#include <fstream>
#include "SuperBlock.h"

using namespace std;

class LowLevelDisk{

public:
	LowLevelDisk();
	int allocateInode(); //V – allocates a new i-node and returns its number
	void freeInode(int inode); // –frees the specified i-node and also frees all the data blocks pointed to by it (directly or indirectly).
	int allocateDataBlock(); // – allocates a data block and returns its number
	void freeDataBlock(int dblock); // – frees the specified block.
	 //Use (and update) the maps in the super block in these allocate/free methods.
	int getInodeType(int inode); // – return the type of the file (normal/directory/soft-link).
	void setInodeType(int inode, char filetype); // – set the type of the file (normal/directory/soft-link).
	int getDataBlock (int inode, int i); // – return the number of the i-th data block containing the data of this file (for 0<=i<=9 this is just stored in the 10 pointers in this inode, for i>9, you must retrieve it from the indirect data block..).
	void setDataBlock (int inode, int i, int dblockNum ); // – sets the i-th data block of this file to be dblockNum.
	void readBlock(int dblockNum, char* buf) ; //– read the entire content of the dblockNum's and copy it into buf.
	void writeBlock(int dblockNum, char* newdata); // – overwrite the content of block with number dblockNum with the newdata block. Assume newdata's length is equal to dataBlockSize.
	int getFileSize(int inode); // – return the file size saved in the given i-node. This is the exact size of the file in bytes, not the number of blocks used by this file.
	int getFileSize1(int inode);
	void setFileSize(int inode, int newSize); // – set the file size.
	int getHardLinksNumber(int inode);
	void setHardLinksNumber(int inode, int num);
	void incHardlinksNumber(int inode);
	/*Regular files simply store the data written to them by user programs. A directory file stores a sequence of directory entries, each of which having the following structure:
	i-node number [4 bytes].
	file name [12 bytes].

	Note – file names in dir-entries are kept without their path (so the file name of /ab/cd.out is just 'cd.out' ).
	Note – all services mentioned above should return appropriate error codes to stderr, when things go bad (for example: requesting to free an i-node that was not allocated, requesting to allocate an i-node when there are none free, asking for the file name of a free i-node, asking the 34th data block of a file that contains only 30 data blocks, etc.).
*/

	// our function:
	void setFileSys(FILE* file, SuperBlock* sb); // V
	int getBlockSize(); // V
	void setFreeInodesAddressesBlock(); // V
	void freeAtachedBlocks(int inode);
	void InitInode (int inode);
	void setInodeHardlinksNumber(int inode, int num);
	Inode newInode();
	 void printInode(Inode n);
	 int getEntriesPerBlock();

private:
	FILE* _FILE_SYS;
	SuperBlock* _superBlock;
	void iNodeBlockSwap();
	int getAddrFromPointer(int addr);
	void addToFreeInodeList(int num);
    void addToFreeBlockList(int block);
	bool isLastEntry(int addr);
//  void removeFromFreeInode(int num);
//  void removeFromFreeBlockList(int blockNum);
    int blockNumToAddr(int num);
    void freeblocksBlockSwap();
    int blockAddrToNum(int adr);

    Inode getInode(int inodeNum);
    void updateInode(int inode, Inode n);


};


#endif /* LOWLEVELDISK_H_ */
